﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Configuration;
using System.Reflection;
using System.Text.RegularExpressions;
/// <summary>
/// 作为Windows服务自动启动Bat或者Cmd文件
/// </summary>
namespace AutoStartAsWindowsService
{
    public partial class AutoStartService : ServiceBase
    {
        static String logFilePath = "AutoStartService.log";//默认的日志文件路径
        static String exeFilePath = Assembly.GetExecutingAssembly().Location;//Exe文件所在路径
        public AutoStartService()
        {
            InitializeComponent();
            exeFilePath = exeFilePath.Substring(0, exeFilePath.LastIndexOf('\\'));//从Exe文件全路径名称中截取获得Exe文件所在的文件夹名称
            String logFilePathTmp = ConfigurationManager.AppSettings["logFilePath"];//从配置文件中读取配置的日志文件路径，并存入临时变量logFilePathTmp中
            //如果临时的日志文件路径不为空
            if (!String.IsNullOrWhiteSpace(logFilePathTmp)) {
                //判断文件路径地址是否完整的文件路径地址，如：C:\xxx.xxx或者Z:\xxx\xxx.xxx格式
                Regex reg = new Regex(@"^[A-Za-z]{1}:[\/].+$");
                //如果不是完整的文件路径地址，则使用Exe文件所在路径+临时的日志文件路径拼接成完整的文件路径地址
                if (!reg.IsMatch(logFilePathTmp)) {
                    logFilePathTmp = exeFilePath + "\\" + logFilePathTmp;
                }
            }
            //如果临时的日志文件路径为空，则使用Exe文件所在路径+默认的日志文件路径拼接成完整的文件路径地址
            if (String.IsNullOrWhiteSpace(logFilePathTmp)) {
                logFilePathTmp = exeFilePath + "\\" + logFilePath;
            }
            try
            {
                //如果临时的日志文件路径所在的文件夹不存在，则创建该文件夹
                if (!System.IO.Directory.Exists(logFilePathTmp.Substring(0, logFilePathTmp.LastIndexOf('\\'))))
                {
                    System.IO.Directory.CreateDirectory(logFilePathTmp.Substring(0, logFilePathTmp.LastIndexOf('\\')));
                }
            }
            catch {
                //如果文件夹不存在并且创建文件夹失败，则使用Exe文件所在路径+默认的日志文件路径拼接成完整的文件路径地址作为默认的日志文件路径
                logFilePath = exeFilePath + "\\" + logFilePath;
                return;
            }
            try
            {
                if (!System.IO.File.Exists(logFilePathTmp))
                {
                    //如果临时的日志文件不存，则创建该日志文件
                    using (System.IO.StreamWriter sw = new System.IO.StreamWriter(logFilePathTmp, true))
                    {
                        sw.Write(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff\t") + "创建该日志文件\r\n");
                    }
                }
                //将临时的日志文件路径正式赋值给默认的日志文件路径
                logFilePath = logFilePathTmp;
                return;
            }
            catch
            {
                //如果临时的日志文件不存并且尝试创建该文件时出错，则使用Exe文件所在路径+默认的日志文件路径拼接成完整的文件路径地址作为默认的日志文件路径
                logFilePath = exeFilePath + "\\" + logFilePath;
                return;
            }
        }
        /// <summary>
        /// 追加时间并换行写入日志信息
        /// </summary>
        /// <param name="message">日志内容</param>
        protected void LogWriteLineWithTime(String message) {
            LogWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff\t")+message+"\r\n");
        }

        /// <summary>
        /// 追加时间写入日志信息
        /// </summary>
        /// <param name="message">日志内容</param>
        protected void LogWriteWithTime(String message)
        {
            LogWrite(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff\t") + message );
        }

        /// <summary>
        /// 换行写入日志信息
        /// </summary>
        /// <param name="message">日志内容</param>
        protected void LogWriteLine(String message)
        {
            LogWrite(message + "\r\n");
        }
        /// <summary>
        /// 写入日志信息
        /// </summary>
        /// <param name="message">日志内容</param>
        protected void LogWrite(String message)
        {
            using (System.IO.StreamWriter sw = new System.IO.StreamWriter(logFilePath, true))
            {
                sw.Write(message);
            }
        }
        /// <summary>
        /// 启动批处理文件
        /// </summary>
        /// <param name="batName">批处理文件名称，不带扩展名称</param>
        protected void StartBat(String batName)
        {
            if (System.IO.File.Exists(exeFilePath + "\\" + batName + ".cmd"))
            {
                batName = exeFilePath + "\\" + batName + ".cmd";
            }
            else if (System.IO.File.Exists(exeFilePath + "\\" + batName + ".bat"))
            {
                batName = exeFilePath + "\\" + batName + ".bat";
            }
            else{
                LogWriteLineWithTime(exeFilePath + "目录下不存在“" + batName + ".cmd”或者“" + batName + ".bat”文件");
                return;
            }
            try
            {
                Process proc = new Process();
                proc.StartInfo.WorkingDirectory = exeFilePath;
                proc.StartInfo.FileName = batName;
                proc.StartInfo.Arguments = string.Format("10");//this is argument
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;//这里设置DOS窗口不显示，经实践可行
                proc.StartInfo.UseShellExecute = true;
                proc.Start();
                //proc.WaitForExit();
            }
            catch (Exception ex)
            {
                LogWriteLineWithTime("执行"+batName+"时出错，错误信息："+ ex.Message);
            }
        }
        /// <summary>
        /// 服务启动时
        /// </summary>
        /// <param name="args">服务启动参数</param>
        protected override void OnStart(string[] args)
        {
            LogWriteLineWithTime("服务开始启动");
            StartBat("OnStart");
            base.OnStart(args);
            LogWriteLineWithTime("服务启动完毕");
        }
        /// <summary>
        /// 服务停止
        /// </summary>
        protected override void OnStop()
        {
            LogWriteLineWithTime("服务开始停止");
            StartBat("OnStop");
            base.OnStop();
            LogWriteLineWithTime("服务已经停止");
        }
        /// <summary>
        /// 服务暂停
        /// </summary>
        protected override void OnPause()
        {
            LogWriteLineWithTime("服务开始暂停");
            StartBat("OnPause");
            base.OnPause();
            LogWriteLineWithTime("服务已经暂停");
        }
        /// <summary>
        /// 服务继续
        /// </summary>
        protected override void OnContinue()
        {
            LogWriteLineWithTime("服务开始继续");
            StartBat("OnContinue");
            base.OnContinue();
            LogWriteLineWithTime("服务继续");
        }
        /// <summary>
        /// 服务器关机
        /// </summary>
        protected override void OnShutdown()
        {
            LogWriteLineWithTime("开始关机");
            StartBat("OnShutdown");
            base.OnShutdown();
            LogWriteLineWithTime("已经关机");
        }
    }
}
